package JFrame;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

/**
 * 玩游戏时候的面板
 */
public class SnackPanel extends JPanel implements KeyListener, ActionListener {
    //当前用户ID
    String id;
    //定义蛇的数据结构
    //蛇的长度
    int length;
    //蛇每一块的x坐标
    int[] snakeX = new int[600];
    //蛇每一块的y坐标
    int[] snakeY = new int[600];
    //蛇头方向
    String fx;
    //游戏当前状态,默认没开始
    boolean isStart = false;
    //默认没有失败 正在游戏状态
    boolean isFail =false;
    //100毫秒执行一次 1000ms=1s
    //创建一个 Timer并将初始延迟和事件间延迟初始化为 delay毫秒。//该计时器每秒触发一次动作事件
    //GamePanel本身接口了动作监听器
    Timer timer = new Timer(200, this);

    //食物的坐标
    int foodx;
    int foody;
    int foodx2;
    int foody2;

    Random random = new Random(); //用来确定食物位置

    int score;

    /**
     * 构造器
     */
    public SnackPanel(String id) {
        this.id=id;
        init();
        this.setFocusable(true);//获得焦点事件
        this.addKeyListener(this);//获得键盘监听事件
    }

    public void init() {
        length = 3;
        snakeX[0] = 100;
        snakeY[0] = 100;//脑袋的坐标
        snakeX[1] = 75;
        snakeY[1] = 100;//第一个身体的坐标
        snakeX[2] = 50;
        snakeY[2] = 100;//第二个身体的坐标
        fx = "R";//初始化在右
        timer.start();//游戏一开始就启动.  start()启动 Timer,使其开始向其侦听器发送动作事件。
        //GamePanel本身接口了动作监听器 // 该计时器每次触发一次动作事件调用actionPerformed

        foodx = 25 + 25 * random.nextInt(34);//返回从该随机数生成器的序列中提取的伪随机，//int bound
        // 均匀分布的值在0（包括）和指定值（不包括）之间的 int
        foody = 75 + 25 * random.nextInt(24);
        foodx2 = 25 + 25 * random.nextInt(34);
        foody2 = 75 + 25 * random.nextInt(34);
        score=0;
    }


    /**
     * paintComponent()是swing的一个方法，相当于图形版的main()，是会自执行的。执行顺序是先执行构造函数，再执行这个。
     * 绘制面板 游戏中的所有东西都使用这画笔来画
     */
    @Override
    protected void paintComponent(Graphics g) {
        //有清屏作用，消去之前的画面
        super.paintComponent(g);

        //绘制静态面板
        this.setBackground(Color.white);
        //默认游戏界面
        g.fillRect(25, 75, 850, 600);
        //Data.header.paintIcon(this, g, 0, 11);//界面头部
        //画星星
        g.setColor(Color.black);
        g.fillRect(25,0,850,72);
        g.setColor(Color.yellow);
        for (int i=0;i<70;i++){
            int a=(int)(Math.random()*850);
            int b=(int)(Math.random()*72);
            g.drawString(".",a,b);
        }
        //画食物
        Data.food.paintIcon(this, g, foodx, foody);
        Data.food2.paintIcon(this,g,foodx2,foody2);

        //把小蛇画上去
        switch (fx) {
            case "R":
                //蛇头初始化在右
                Data.right.paintIcon(this, g, snakeX[0], snakeY[0]);
                break;
            case "L":
                Data.left.paintIcon(this, g, snakeX[0], snakeY[0]);
                break;
            case "D":
                Data.down.paintIcon(this, g, snakeX[0], snakeY[0]);
                break;
            case "U":
                Data.up.paintIcon(this, g, snakeX[0], snakeY[0]);
                break;
        }


        for (int i = 1; i < length; i++) {
            //画身体
           Data.body.paintIcon(this, g, snakeX[i], snakeY[i]);
        }


        //游戏状态
        if (!isStart) {
            g.setColor(Color.white);
            g.setFont(new Font("微软雅黑", Font.BOLD, 40));
            g.drawString("按下空格开始游戏", 300, 300);
        }

        if (isFail){
            g.setColor(Color.red);
            g.setFont(new Font("微软雅黑", Font.BOLD, 40));
            g.drawString("游戏失败！按下空格重新开始",200,300);
        }
        //画积分
        g.setColor(Color.BLUE);
        g.setFont(new Font("微软雅黑", Font.BOLD, 18));
        g.drawString("长度"+length,750,25);
        g.drawString("分数"+score,750,45);
        //画规则
        g.setColor(Color.CYAN);
        g.setFont(new Font("微软雅黑", Font.BOLD, 18));
        g.drawString("奇怪的方块的加20分",100,45);
        g.drawString("空格暂停",100,25);
        g.drawString("按下esc退出",100,65);
    }

    /**
     * 键盘监听器
     */
    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();


        if (keyCode == KeyEvent.VK_ESCAPE){

            System.exit(0);
        }

        if (keyCode == KeyEvent.VK_SPACE) {
            if (isFail){
                //重新开始
                isFail=false;
                init();
            }else {
                isStart = !isStart; //取反 暂停
                }
        }
        repaint();
        if (keyCode == KeyEvent.VK_UP && !fx.equals("D")) {
            fx = "U";
        } else if (keyCode == KeyEvent.VK_DOWN && !fx.equals("U")) {
            fx = "D";
        } else if (keyCode == KeyEvent.VK_LEFT && !fx.equals("R")) {
            fx = "L";
        } else if (keyCode == KeyEvent.VK_RIGHT&& !fx.equals("L")) {
            fx = "R";
        }
    }

    /**
     * 事件监听 需要通过通过固定的时间来刷新
     * 并使用组件的addActionListener方法向组件注册使用该类创建的对象。 当动作事件发生时，将调用该对象的actionPerformed方法。
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        if (isStart&& !isFail) {
            //如果游戏是开始的 小蛇开始动起来
            if (snakeX[0] == foodx && snakeY[0] == foody) {
                length++;
                //再次随机食物
                foodx = 25 + 25 * random.nextInt(34);
                foody = 75 + 25 * random.nextInt(24);
                score+=10; //一个10分
            }
            if (snakeX[0] == foodx2 && snakeY[0] == foody2) {
                length++;
                //再次随机食物
                foodx2 = 25 + 25 * random.nextInt(34);
                foody2 = 75 + 25 * random.nextInt(24);
                score+=20; //一个20分
            }

            //移动
            for (int i = length - 1; i > 0; i--) {
                snakeX[i] = snakeX[i - 1];//后一节移向前一节
                snakeY[i] = snakeY[i - 1];
            }

            //走向
            switch (fx) {
                case "R":
                    snakeX[0] = snakeX[0] + 25;
                    if (snakeX[0] > 850) {
                        snakeX[0] = 25;
                    }//边界判断
                    break;
                case "L":
                    snakeX[0] = snakeX[0] - 25;
                    if (snakeX[0] < 25) {
                        snakeX[0] = 850;
                    }//边界判断
                    break;
                case "U":
                    snakeY[0] = snakeY[0] - 25;
                    if (snakeY[0] < 75) {
                        snakeY[0] = 650;
                    }//边界判断
                    break;
                case "D":
                    snakeY[0] = snakeY[0] + 25;
                    if (snakeY[0] > 650) {
                        snakeY[0] = 75;
                    }//边界判断
                    break;
            }
            //失败判断
            for (int i=1;i<length;i++){
                if (snakeX[0]==snakeX[i]&&snakeY[0]==snakeY[i]){
                    new TipsJDialog(id,score,"Snack");
                    isFail=true;
                }
            }
            repaint(); //重画
        }
    }

    /**
     * 键盘监听没用到的 空实现
     */
    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

}